/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controls;

import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import others.Console;
import others.Login;
import table.ApplicationPool;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import others.User;
import table.Module;

/**
 *
 * @author Dingo
 */
@ManagedBean
@SessionScoped
public class ModulesControl implements Serializable {

    private String name = null;
    private String type = null;
    private String appName = null;
    private String preCondition = null;
    private String image = null;
    private boolean doAdd = true;
    private List<Module> list = null;
    private Module selectedElement = null;
    @ManagedProperty(value = "#{login}")
    private Login login;

    /** Creates a new instance of ModulesControl */
    public ModulesControl() {
        list = new ArrayList<Module>();
        doList();
    }

    private void doList() {
        String resp = Console.request("c:\\Windows\\System32\\inetsrv\\appcmd list module /xml");
        System.out.print(resp);
        // creating javaDom parser
        DocumentBuilderFactory builderFactory =
                DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = null;
        try {
            builder = builderFactory.newDocumentBuilder();
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(ApplicationPoolsControl.class.getName()).log(Level.SEVERE, null, ex);
        }
        Document document = null;
        try {
            InputSource is = new InputSource();
            is.setCharacterStream(new StringReader(resp));
            document = builder.parse(is);
        } catch (IOException ex) {
            Logger.getLogger(ApplicationPoolsControl.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SAXException ex) {
            Logger.getLogger(ApplicationPoolsControl.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (document != null) {
            Element rootElement = document.getDocumentElement();
            NodeList nodes = rootElement.getChildNodes();

            for (int i = 0; i < nodes.getLength(); i++) {
                Node node = nodes.item(i);
                if (node instanceof Element) {
                    //a child element to process
                    Element child = (Element) node;
                    list.add(new Module(child.getAttribute("MODULE.NAME"),
                            child.getAttribute("precondition"),
                            child.getAttribute("type")));
                }
            }
        }
    }

    public void add(ActionEvent actionEvent) {
        if (login.userPermited(User.PERM_ADMIN)) {
            String query = "c:\\Windows\\System32\\inetsrv\\appcmd add module"
                    + " /name:\"" + name + "\"";
            if (appName != null && !appName.isEmpty()) {
                query += " /app.name:\"" + appName + "\"";
            }
            if (type != null && !type.isEmpty()) {
                query += " /type:\"" + type + "\"";
            }
            String log = Console.request(query);
            FacesMessage msg = null;

            Pattern addedp = Pattern.compile("added");
            Matcher addedm = addedp.matcher(log);
            Pattern dupp = Pattern.compile("duplicate");
            Matcher dupm = dupp.matcher(log);
            Pattern p3 = Pattern.compile("installed");
            Matcher m3 = p3.matcher(log);
            if (addedm.find()) {
                msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Hura!",
                        "Dodano nowy moduł: " + name);
                list.add(new Module(name, appName, type));
                name = null;
                appName = null;
                type = null;
            } else if (dupm.find()) {
                msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Błąd!",
                        "Dodawany moduł już istnieje. Nazwa musi być unikatowa!");
            } else if (m3.find()) {
                msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Błąd!",
                        "Dodawany moduł musi być zainstalowany!");
            } else {
                msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Błąd!",
                        "Spróbuj ponownie. Sprawdź poprawność danych!");
            }
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public void install(ActionEvent actionEvent) {
        if (login.userPermited(User.PERM_ADMIN)) {
            String query = "c:\\Windows\\System32\\inetsrv\\appcmd install module"
                    + " /name:\"" + name + "\" /image:\"" + image + "\"";
            if (doAdd == true) {
                query += " /add:true";
            } else {
                query += " /add:false";
            }
            String log = Console.request(query);
            FacesMessage msg = null;
            System.out.println(query);
            Pattern addedp = Pattern.compile("added");
            Matcher addedm = addedp.matcher(log);
            Pattern dupp = Pattern.compile("duplicate");
            Matcher dupm = dupp.matcher(log);
            if (addedm.find()) {
                msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Hura!",
                        "Dodano nowy moduł: " + name);
                if (doAdd) {
                    list.add(new Module(name, null, null));
                }
                name = null;
                image = null;
                doAdd = false;
            } else if (dupm.find()) {
                msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Błąd!",
                        "Dodawany moduł już istnieje. Nazwa musi być unikatowa!");
            } else {
                msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Błąd!",
                        "Spróbuj ponownie. Sprawdź poprawność danych!");
            }

            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public void delete(ActionEvent actionEvent) {
        if (login.userPermited(User.PERM_ADMIN) && selectedElement != null) {
            String query = "c:\\Windows\\System32\\inetsrv\\appcmd delete module "
                    + "\"" + selectedElement.getName() + "\"";
            String log = Console.request(query);
            FacesMessage msg = null;
            Pattern p = Pattern.compile("deleted");
            Matcher m = p.matcher(log);
            if (m.find()) {
                msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Hura!",
                        "Usunięto moduł: " + selectedElement.getName());
                list.remove(selectedElement);
            } else {
                msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Błąd!",
                        "Nieusunięto modułu: " + selectedElement.getName() + ". Sprawdź dane.");
            }

            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public void modify(ActionEvent actionEvent) {
        if (login.userPermited(User.PERM_ADMIN) && selectedElement != null) {
            String query = "c:\\Windows\\System32\\inetsrv\\appcmd set module "
                    + "\"" + selectedElement.getName() + "\" /preCondition:\""
                    + preCondition + "\"";
            if (appName != null && !appName.isEmpty()) {
                query += " /app.name:\"" + appName + "\"";
            }
            String log = Console.request(query);
            FacesMessage msg = null;
            Pattern p = Pattern.compile("changed");
            Matcher m = p.matcher(log);
            if (m.find()) {
                msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Hura!",
                        "Zmodyfikowano moduł: " + selectedElement.getName());
                selectedElement.setPreCondition(preCondition);
            } else {
                msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Błąd!",
                        "Niezmodyfikowano modułu: " + selectedElement.getName() + ". Sprawdź dane.");
            }
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public void uninstall(ActionEvent actionEvent) {
        if (login.userPermited(User.PERM_ADMIN) && selectedElement != null) {
            String query = "c:\\Windows\\System32\\inetsrv\\appcmd uninstall module "
                    + "\"" + selectedElement.getName() + "\"";
            String log = Console.request(query);
            FacesMessage msg = null;
            Pattern p = Pattern.compile("Uninstalled");
            Matcher m = p.matcher(log);
            if (m.find()) {
                msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Hura!",
                        "Odinstalowano moduł: " + selectedElement.getName());
            } else {
                msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Błąd!",
                        "Nie odinstalowano modułu: " + selectedElement.getName() + ". Sprawdź dane.");
            }

            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public List<Module> getList() {
        return list;
    }

    public void setList(List<Module> list) {
        this.list = list;
    }

    public Login getLogin() {
        return login;
    }

    public void setLogin(Login login) {
        this.login = login;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Module getSelectedElement() {
        return selectedElement;
    }

    public void setSelectedElement(Module selectedElement) {
        this.selectedElement = selectedElement;
    }

    public String getAppName() {
        return appName;
    }

    public void setAppName(String appName) {
        this.appName = appName;
    }

    public String getTyp() {
        return type;
    }

    public void setTyp(String type) {
        this.type = type;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public boolean isDoAdd() {
        return doAdd;
    }

    public void setDoAdd(boolean doAdd) {
        this.doAdd = doAdd;
    }

    public String getPreCondition() {
        return preCondition;
    }

    public void setPreCondition(String preCondition) {
        this.preCondition = preCondition;
    }
}
